package com.hgkj.cloud.customer.util;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.apache.commons.lang.time.FastDateFormat;

/**
 * 日期操作的Util类.
 */
public class DateUtil {
	public static final String		YYYY = "yyyy";
	public static final String		MM = "MM";
	public static final String		DD = "dd";
	public static final String		HH24 = "HH";
	public static final String		MI = "mm";
	public static final String		MM_DD = "MM-dd";
	public static final String		YYYY_MM_DD = "yyyy-MM-dd";
	public static final String		YYYY_MM_DD_HH_MI = "yyyy-MM-dd HH:mm";
	public static final String		YYYY_MM_DD_HH_MI_SS = "yyyy-MM-dd HH:mm:ss";
	public static final String		MM_DD_HH_MI = "MM-dd HH:mm";
	public static final String		ISO8601 = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
	public static final String		YYYYMMDD = "yyyyMMdd";
	public static final String		YYYYMM = "yyyyMM";
	public static final String		YYYY_MM = "yyyy-MM";
	
	public static final FastDateFormat normalDateFormatter = FastDateFormat.getInstance(YYYY_MM_DD);
	public static final FastDateFormat shortDateFormatter = FastDateFormat.getInstance(MM_DD);
	public static final FastDateFormat datetimeDateFormatter = FastDateFormat.getInstance(YYYY_MM_DD_HH_MI);
	public static final FastDateFormat allDateFormatter = FastDateFormat.getInstance(YYYY_MM_DD_HH_MI_SS);
	public static final FastDateFormat iso8601Formatter = FastDateFormat.getInstance(ISO8601, TimeZone.getTimeZone("Etc/UTC"));

    public static final int MILLIS_PER_SECOND = 1000;
    public static final int MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND;
    public static final int MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE;

    public static final int TIMEZONE_OFFSET = TimeZone.getDefault().getRawOffset();
	
	private DateUtil(){
	}
	
	/**
	 * 按指定格式显示日期.
	 * 
	 * @param d 日期
	 * @param pattern 格式
	 * 
	 * @return the string
	 */
	public static String show(Date d, String pattern){
		if(d == null) return "";
		
		FastDateFormat formatter = FastDateFormat.getInstance(pattern);
		return formatter.format(d);
	}
	
	/**
	 * 缺省格式显示日期(yyyy-MM-dd).
	 * 
	 * @param d 日期
	 * 
	 * @return the string
	 */
	public static String show(Date d){
		if(d == null) return "";
		return normalDateFormatter.format(d);
	}
	
	/**
	 * yyyy-MM-dd HH:mm格式显示日期.
	 * 
	 * @param d 日期
	 * 
	 * @return the string
	 */
	public static String showDatetime(Date d){
		if(d == null) return "";
		return datetimeDateFormatter.format(d);
	}
	
	/**
	 * yyyy-MM-dd HH:mm:ss格式显示日期.
	 * 
	 * @param d 日期
	 * 
	 * @return the string
	 */
	public static String showAll(Date d){
		if(d == null) return "";
		return allDateFormatter.format(d);
	}
	
	/**
	 * MM-dd格式显示日期.
	 * 
	 * @param d 日期
	 * 
	 * @return the string
	 */
	public static String showShort(Date d){
		if(d == null) return "";
		return shortDateFormatter.format(d);
	}
	
	/**
	 * yyyy-MM-dd'T'HH:mm:ss.SSS'Z'格式显示日期.
	 * <p>DateFormat.getInstance(ISO8601, TimeZone.getTimeZone("Etc/UTC"))</p>
	 * @param d 日期
	 * 
	 * @return the string
	 */
	public static String showISO8601(Date d){
		if(d == null) return "";
		return iso8601Formatter.format(d);
	}

	/**
	 * 解析字符串为日期.
	 * 
	 * @param s 日期字符串
	 * @param pattern 格式
	 * 
	 * @return the java.util.Date
	 */
	public static Date parse(String s,String pattern){
		if(s == null || s.length() == 0 || s.startsWith("0000-00-00")) {
			return null;
		}
		SimpleDateFormat bartDateFormat = new SimpleDateFormat(pattern); 
		try { 
			return bartDateFormat.parse(s);
		}catch (Exception ex) { 
			System.out.println("parseDate: " + ex.getMessage());
			return null;
		} 
	}
	
	/**
	 * 解析字符串为日期，格式yyyy-MM-dd.
	 * 
	 * @param s 日期字符串
	 * 
	 * @return the java.util. date
	 */
	public static Date parse(String s){
		Date date = parse(s,YYYY_MM_DD);
		if(date != null){
			date.setTime(date.getTime() + 12*MILLIS_PER_HOUR);
		}
		return date;
	}
	
	/**
	 * 解析字符串为日期，格式YYYY_MM_DD_HH_MI_SS
	 * 
	 * @param s 日期字符串
	 * 
	 * @return the java.util. date
	 */
	public static Date parseall(String s){
		Date date = parse(s,YYYY_MM_DD_HH_MI_SS);
		if(date != null){
			date.setTime(date.getTime() + 24*MILLIS_PER_HOUR);
		}
		return date;
	}
	
	/**
	 * 将php函数取得的时间，转换为<code>java.util.Date</code>.
	 * <p>已考虑当前服务器所在时区的offset, TimeZone.getDefault().getRawOffset()</p>
	 * @param timestamp php时间
	 * 
	 * @return the java.util.Date
	 */
	public static Date fromPhpTime(int timestamp){
		if(timestamp == 0) return null;
		
		long l = (long)(timestamp) * 1000 + TIMEZONE_OFFSET;
		return new Date(l);
	}
	
	/**
	 * 将java.util.Date转换为php时间.
	 * 
	 * @param d 日期
	 * 
	 * @return php时间
	 */
	public static int toPhpTime(Date d){
		if(d == null) return 0;
		
		long l = d.getTime() - TIMEZONE_OFFSET;
		return (int)(l/1000);
	}

	/**
	 * 返回2个日期相差的天数.
	 * <p>to不要求大于from</p>
	 * 
	 * @param from 开始日期
	 * @param to 截止日期
	 * 
	 * @return 天数
	 */
	public static int getDays(Date from, Date to){
		if(from == null || to == null) return 0;
		
		Calendar cFrom = Calendar.getInstance();
		cFrom.setTime(from);
		cFrom.set(Calendar.HOUR_OF_DAY,8);
		cFrom.set(Calendar.MINUTE,30);
		cFrom.set(Calendar.SECOND,0);
		
		Calendar cTo = Calendar.getInstance();
		cTo.setTime(to);
		cTo.set(Calendar.HOUR_OF_DAY,9);
		
		long gap = cTo.getTimeInMillis() - cFrom.getTimeInMillis();
		if(gap <=0) {
			cTo.set(Calendar.HOUR_OF_DAY,7);
			gap = cFrom.getTimeInMillis() - cTo.getTimeInMillis();
			return 0 - (int)(gap / (24*MILLIS_PER_HOUR));
		}else{
			return (int)(gap / (24*MILLIS_PER_HOUR));
		}
	}

	public static long getHours(Date from, Date to) {
		long gap = to.getTime()-from.getTime();
		return Math.abs(gap/MILLIS_PER_HOUR);
	}

	/**
	 * 返回日期与今天相差的天数.
	 * to=today
	 * @param from 日期
	 * 
	 * @return 天数
	 */
	public static int getDays(Date from){
		return getDays(from,new Date());
	}

	public static void main(String[] args) {
		Date from = new Date(114,10,5);
		System.out.println(getDays(from,Calendar.getInstance().getTime()));
	}
	/**
	 * 日期所在的星期一.
	 * 
	 * @param d 日期
	 * 
	 * @return the week start
	 */
	public static int getWeekStart(Date d){
		Calendar c = Calendar.getInstance();
		c.setTime(d);
		while(c.get(Calendar.DAY_OF_WEEK)!=Calendar.MONDAY){
			c.add(Calendar.DATE, -1);
		}
		
		return c.get(Calendar.YEAR)*10000
			+ (c.get(Calendar.MONTH)+1)*100
			+ c.get(Calendar.DATE);
	}
	
	/**
	 * 日期所在的星期一.
	 * 
	 * @param dateId yyyymmdd型的整数
	 * 
	 * @return the week start
	 */
	public static int getWeekStart(int dateId){
		try{
			SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd");
			Date d = f.parse(String.valueOf(dateId));
			return getWeekStart(d);
		}catch(Exception e){
			System.err.println("getWeekStart, Invalid date=" + dateId);
			return 0;
		}
	}
	
	/**
	 * 日期所在的星期日.
	 * 
	 * @param d 日期
	 * 
	 * @return the week end
	 */
	public static int getWeekEnd(Date d){
		Calendar c = Calendar.getInstance();
		c.setTime(d);
		while(c.get(Calendar.DAY_OF_WEEK)!=Calendar.SUNDAY){
			c.add(Calendar.DATE, 1);
		}
		
		return c.get(Calendar.YEAR)*10000
			+ (c.get(Calendar.MONTH)+1)*100
			+ c.get(Calendar.DATE);
	}
	
	/**
	 * 日期所在的星期日.
	 * 
	 * @param dateId yyyymmdd型的整数
	 * 
	 * @return the week end
	 */
	public static int getWeekEnd(int dateId){
		try{
			SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd");
			Date d = f.parse(String.valueOf(dateId));
			return getWeekEnd(d);
		}catch(Exception e){
			System.err.println("getWeekEnd, Invalid date=" + dateId);
			return 0;
		}
	}
	
	/**
	 * 取下个星期一.
	 * 
	 * @param weekStart 这个星期一
	 * 
	 * @return the next week start
	 */
	public static int getNextWeekStart(int weekStart){
		try{
			SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd");
			Date d = f.parse(String.valueOf(weekStart));
			Calendar c = Calendar.getInstance();
			c.setTime(d);
			c.add(Calendar.DATE, 7);
			
			return c.get(Calendar.YEAR)*10000
				+ (c.get(Calendar.MONTH)+1)*100
				+ c.get(Calendar.DATE);
		}catch(Exception e){
			System.err.println("getNextWeekStart, Invalid date=" + weekStart);
			return 0;
		}
	}
	
	/**
	 * 根据日期生成yyyymmdd型的整数.
	 * 
	 * @param d 日期
	 * @param incDay 天数增量
	 * 
	 * @return int
	 */
	public static int getDateId(Date d, int incDay){
		Calendar c = Calendar.getInstance();
		c.setTime(d);
		if(incDay != 0){
			c.add(Calendar.DATE, incDay);
		}

		return c.get(Calendar.YEAR)*10000
			+ (c.get(Calendar.MONTH)+1)*100
			+ c.get(Calendar.DATE);
	}

	/**
	 * 根据日期生成yyyymmdd型的整数.
	 * 
	 * @param d 日期
	 * 
	 * @return int
	 */
	public static int getDateId(Date d){
		return getDateId(d,0);
	}
	
	/**
	 * 返回calendar对象.
	 * 
	 * @param dateId yyyymmdd型的整数
	 * @param incDay 天数增量
	 * 
	 * @return the calendar
	 */
	public static Calendar getCalendar(int dateId, int incDay){
		Calendar c = Calendar.getInstance();
		
		c.set(Calendar.YEAR, dateId/10000);
		int i = dateId % 10000;
		c.set(Calendar.MONTH, i/100-1);
		c.set(Calendar.DATE, i%100+incDay);
		
		return c;
	}
	
	/**
	 * 返回calendar对象.
	 * 
	 * @param dateId yyyymmdd型的整数
	 * 
	 * @return the calendar
	 */
	public static Calendar getCalendar(int dateId){
		return getCalendar(dateId,0);
	}
	
	/**
	 * 返回java.util.Date对象.
	 * 
	 * @param dateId yyyymmdd型的整数
	 * @param incDay 天数增量
	 * 
	 * @return 日期
	 */
	public static Date getDate(int dateId,int incDay){
		return getCalendar(dateId,incDay).getTime();
	}

	/**
	 * 返回java.util.Date对象.
	 * 
	 * @param dateId yyyymmdd型的整数
	 * 
	 * @return 日期
	 */
	public static Date getDate(int dateId){
		return getCalendar(dateId,0).getTime();
	}
	
	/**
	 * 根据入学年份返回当前年级数.
	 * 
	 * @param 入学年份
	 * 
	 * @return 年级
	 */
	public static String getGrade(String year){
		Calendar now = Calendar.getInstance();
		int grade = 1;
		if(now.get(Calendar.YEAR) == Integer.valueOf(year))
			grade = 1;
		else if(now.get(Calendar.YEAR) > Integer.valueOf(year)){
			if(now.get(Calendar.MONTH) + 1 >= 9)
				grade = now.get(Calendar.YEAR) - Integer.valueOf(year) + 1;
			else
				grade = now.get(Calendar.YEAR) - Integer.valueOf(year);
		}
			
		return String.valueOf(grade)+"年级";
	}
	
	/**
     * 将秒数转换为日时分秒，
     * @param second
     * @return
     */
    public static String secondToTime(long second){
        long days = second / 86400;            //转换天数
        second = second % 86400;            //剩余秒数
        long hours = second / 3600;            //转换小时
        second = second % 3600;                //剩余秒数
        long minutes = second /60;            //转换分钟
        second = second % 60;                //剩余秒数
        if(days>0){
            return days + "天" + hours + "小时" + minutes + "分" + second + "秒";
        }else{
            return hours + "小时" + minutes + "分" + second + "秒";
        }
    }
    
    /**
     * 将秒数转换为日时分秒   9:30:20，
     * @param second
     * @return
     */
    public static String secondToTime2(long second){
        long days = second / 86400;            //转换天数
        second = second % 86400;            //剩余秒数
        long hours = second / 3600;            //转换小时
        second = second % 3600;                //剩余秒数
        long minutes = second /60;            //转换分钟
        second = second % 60;                //剩余秒数
        if(days>0){
            return days + ":" + (hours>9?hours:"0"+Long.toString(hours)) + ":" + (minutes>9?minutes:"0"+Long.toString(minutes)) + ":" + (second>9?second:"0"+Long.toString(second));
        }else{
            return (hours>9?hours:"0"+Long.toString(hours)) + ":" + (minutes>9?minutes:"0"+Long.toString(minutes)) + ":" + (second>9?second:"0"+Long.toString(second));
        }
    }
    
    /**
     * 日期转星期
     * 
     * @param datetime
     * @return
     */
    public static String dateToWeek(String datetime) {
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        String[] weekDays = { "7", "1", "2", "3", "4", "5", "6" };
        Calendar cal = Calendar.getInstance(); // 获得一个日历
        Date datet = null;
        try {
            datet = f.parse(datetime);
            cal.setTime(datet);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。
        if (w < 0)
            w = 0;
        return weekDays[w];
    }

    public static String dateToWeekStr(String datetime) {
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        String[] weekDays = { "sun_times", "mon_times", "tue_times", "wed_times", "thu_times", "fri_times", "sat_times" };
        Calendar cal = Calendar.getInstance(); // 获得一个日历
        Date datet = null;
        try {
            datet = f.parse(datetime);
            cal.setTime(datet);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。
        if (w < 0)
            w = 0;
        return weekDays[w];
    }
    /**
     * 前一个月 、前三个月、一年前的日期
     * 
     * @param months
     * @return
     */
    public static String dateBack(Integer months) {
    	Date dNow = new Date();   //当前时间
		Date dBefore = new Date();
		Calendar calendar = Calendar.getInstance(); //得到日历
		calendar.setTime(dNow);//把当前时间赋给日历
		calendar.add(Calendar.MONTH, months);  //设置为前3月
		dBefore = calendar.getTime();   //得到前3月的时间
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //设置时间格式
		String defaultStartDate = sdf.format(dBefore);    //格式化前3月的时间
		return defaultStartDate;
    }

	public static String timeStampToDate(String s){
		String res;
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		long lt = new Long(s+"000");
		Date date = new Date(lt);
		res = simpleDateFormat.format(date);
		return res;
	}
}

